/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package pages;

import com.mathworks.toolbox.javabuilder.MWNumericArray;
import ipa.Ipa;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.context.FacesContext;
import javax.imageio.ImageIO;
import org.primefaces.event.FileUploadEvent;
import org.primefaces.model.DefaultStreamedContent;
import org.primefaces.model.StreamedContent;
import org.primefaces.model.UploadedFile;

/**
 *
 * @author Peter
 */
@ManagedBean
@SessionScoped
public class Index {

    private UploadedFile uploadedImage1;
    private UploadedFile uploadedImage2;
    private StreamedContent image1;
    private StreamedContent image2;
    private StreamedContent resultImage;
    private boolean resultRendered = false;

    public boolean isResultRendered() {
        return resultRendered;
    }

    public void setResultRendered(boolean resultRendered) {
        this.resultRendered = resultRendered;
    }

    public StreamedContent getResultImage() {
        return resultImage;
    }

    public void setResultImage(StreamedContent resultImage) {
        this.resultImage = resultImage;
    }

    public StreamedContent getImage1() {
        return image1;
    }

    public void setImage1(StreamedContent image1) {
        this.image1 = image1;
    }

    public StreamedContent getImage2() {
        return image2;
    }

    public void setImage2(StreamedContent image2) {
        this.image2 = image2;
    }

    /** Creates a new instance of Index */
    public Index() {
        setDefaultImages();
    }

    public void handleFileUpload1(FileUploadEvent event) {
        uploadedImage1 = event.getFile();
        try {
            image1 = new DefaultStreamedContent(uploadedImage1.getInputstream(), uploadedImage1.getContentType());
        } catch (IOException ex) {
            showError(ex, uploadedImage1.getFileName() + " is not uploaded.");
        }

    }

    private void showError(Exception ex, String message) {
        //Logger.getLogger(Index.class.getName()).log(Level.SEVERE, null, ex);
        FacesMessage msg = new FacesMessage("Error", message);
        FacesContext.getCurrentInstance().addMessage("message", msg);
    }

    public void handleFileUpload2(FileUploadEvent event) {
        uploadedImage2 = event.getFile();
        try {
            image2 = new DefaultStreamedContent(uploadedImage2.getInputstream(), uploadedImage2.getContentType());
        } catch (IOException ex) {
            showError(ex, uploadedImage2.getFileName() + " is not uploaded.");
        }
    }

    private void setDefaultImages() {
        InputStream stream = this.getClass().getResourceAsStream("/../../images/img1.png");
        image1 = new DefaultStreamedContent(stream, "image/png");
        stream = this.getClass().getResourceAsStream("/../../images/img2.png");
        image2 = new DefaultStreamedContent(stream, "image/png");
    }

    public String joinByColumns() {
        if (uploadedImage1 == null || uploadedImage2 == null) {
            FacesMessage msg = new FacesMessage("Error", "Both images have to be uploaded.");
            FacesContext.getCurrentInstance().addMessage(null, msg);
            return null;
        }
        try {
            BufferedImage bi1 = ImageIO.read(uploadedImage1.getInputstream());
            BufferedImage bi2 = ImageIO.read(uploadedImage2.getInputstream());

            Ipa ipa = new Ipa();
            int w1 = bi1.getWidth();
            int w2 = bi2.getWidth();

            int h1 = bi1.getHeight();
            int h2 = bi2.getHeight();

            MWNumericArray data1 = getMWArray(w1, h1, bi1);
            MWNumericArray data2 = getMWArray(w2, h2, bi2);

            Object[] result = ipa.ipacolumn(1, w1, h1, data1, w2, h2, data2);

            resultImage = getDSCImage(result);
            resultRendered = true;
        } catch (IOException ex) {
            showError(ex, "No image displayed");
        } catch (Exception ex) {
            showError(ex, " error");
        } finally {
            System.gc();
            System.runFinalization();            
        }
        return null;
    }

    public String joinByRows() {
        if (uploadedImage1 == null || uploadedImage2 == null) {
            FacesMessage msg = new FacesMessage("Error", "Both images have to be uploaded.");
            FacesContext.getCurrentInstance().addMessage(null, msg);
            return null;
        }
        try {
            BufferedImage bi1 = ImageIO.read(uploadedImage1.getInputstream());
            BufferedImage bi2 = ImageIO.read(uploadedImage2.getInputstream());

            Ipa ipa = new Ipa();
            int w1 = bi1.getWidth();
            int w2 = bi2.getWidth();

            int h1 = bi1.getHeight();
            int h2 = bi2.getHeight();

            MWNumericArray data1 = getMWArray(w1, h1, bi1);
            MWNumericArray data2 = getMWArray(w2, h2, bi2);

            Object[] result = ipa.iparow(1, w1, h1, data1, w2, h2, data2);

            resultImage = getDSCImage(result);
            resultRendered = true;
        } catch (IOException ex) {
            showError(ex, "No image displayed");
        } catch (Exception ex) {
            showError(ex, ex.getMessage());
        } finally {
            System.gc();
            System.runFinalization();
        }
        return null;
    }

    private MWNumericArray getMWArray(int w, int h, BufferedImage bimage) {
        int[] iArray = new int[w * h * 3];
        int[] pix = bimage.getData().getPixels(0, 0, w, h, iArray);
        MWNumericArray mw = new MWNumericArray(pix);
        return mw;
    }

    private DefaultStreamedContent getDSCImage(Object[] result) throws IOException {
        MWNumericArray numericImageByteArray = (MWNumericArray) result[0];
        byte[] imageByteArray = numericImageByteArray.getByteData();
        InputStream is = new ByteArrayInputStream(imageByteArray);
        return new DefaultStreamedContent(is, "image/png", "result.png");
    }
}
